home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / dosutil / stuff.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  5KB  |  181 lines

  1. /*
  2.  * Keyboard buffer stuffer
  3.  *
  4.  * This program copies characters from the command line into the PC
  5.  * keyboard buffer, adding correct "scan code" extensions as it does so.
  6.  * Numerous "escape sequences" are recognized to provide for stuffing
  7.  * non-ASCII characters produced by the various non-alphanumeric keys on
  8.  * the PC keyboard.
  9.  *
  10.  * The default BIOS keyboard buffer holds only 15 entries, however this
  11.  * program uses the START/END pointers from BIOS, so it should work
  12.  * correctly with the various utilities that enlarge the buffer.
  13.  *
  14.  * Copyright 1994 Dave Dunfield
  15.  * All rights reserved.
  16.  *
  17.  * Permission granted for personal (non-commerical) use only.
  18.  *
  19.  * Compile command: CC stuff -fop
  20.  */
  21. #include <stdio.h>
  22.  
  23. #define    BIOS_SEG        0x40    /* BIOS data segment */
  24. #define    BUFFER_START    0x80    /* Pointer to start of keyboard buffer */
  25. #define    BUFFER_END        0x82    /* Pointer to end of keyboard buffer */
  26. #define    BUFFER_TAIL        0x1A    /* Pointer to next character to receive */
  27. #define    BUFFER_HEAD        0x1C    /* Pointer to first available spot */
  28.  
  29. /* Prefix codes for "ALPHA" keys */
  30. char alpha_prefix[] = {
  31.     0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24,
  32.     0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14,
  33.     0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C };
  34.  
  35. /* Codes for misc. ASCII keys */ 
  36. unsigned ascii_prefix[] = {
  37.     0x3920, 0x0231, 0x0332, 0x0433, 0x0534, 0x0635, 0x0736, 0x0837, 
  38.     0x0938, 0x0A39, 0x0B30, 0x0C2D, 0x0D3D, 0x2B5C, 0x297E, 0x0221, 
  39.     0x0340, 0x0423, 0x0524, 0x0625, 0x0826, 0x092A, 0x0A28, 0x0B29,
  40.     0x0C5F, 0x0D2B, 0x2B7C, 0x1A5B, 0x1B5D, 0x273B, 0x2827, 0x332C,
  41.     0x342E, 0x352F, 0x1A7B, 0x1B7D, 0x273A, 0x2822, 0x333C, 0x343E,
  42.     0x353F, 0x2960, 0 };
  43.  
  44. /* Table of special keys & codes */
  45. char misc_key[] = {
  46.     '=', '!', '/', '\\',            /* Enter, Backspace, Tab, Backtab */
  47.     '@','#','$', '+', '-',            /* Escape, Ins, Del, keypad+, keypad- */
  48.     '<', '>', '{', '}',                /* Right, Left, Up, Down */
  49.     '(', ')', '[', ']',                /* Home, End, PgUp, PgDn */
  50.     '^' };                            /* Single '^' */
  51. unsigned misc_code[] = {
  52.     0x1C0D, 0x0E08, 0x0F09, 0x0F00,
  53.     0x011B, 0x5200, 0x5300, 0x4E2b, 0x4A2D,
  54.     0x4B00, 0x4D00, 0x4800, 0x5000,
  55.     0x4700, 0x4F00, 0x4900, 0x5100,
  56.     0x075E };
  57.  
  58. /* Help text */
  59. char *help[] = {
  60.     "\nKeyboard buffer stuffer - by Dave Dunfield\n",
  61.     "\nUse: stuff <characters>\n\n",
  62.     "^ indicates special characters:\n\n",
  63.     " ^A-Z Ctrl  ^*A-Z Alt  ^.0-9 Fn  ^,0-9 SFn  ^:0-9 CFn  ^;0-9 AFn\n\n",
  64.     " ^^ (^)     ^= Enter   ^@ Esc    ^! Backsp  ^/ Tab     ^\\ Backtab\n",
  65.     " ^< Right   ^> Left    ^{ Up     ^} Down    ^[ PgUp    ^] PgDn\n",
  66.     " ^( Home    ^) End     ^+ Kpad+  ^- Kpad-   ^# Ins     ^$ Del\n",
  67.     " ^? Clear keyboard buffer\n",
  68.     0 };
  69.  
  70. /* 
  71.  * Main program - Stuff arguments into the keyboard buffer
  72.  */
  73. main(argc, argv)
  74.     int argc;
  75.     char *argv[];
  76. {
  77.     int i;
  78.  
  79.     if(argc < 2) {        /* No data to stuff, display help */
  80.         for(i=0; help[i]; ++i)
  81.             fputs(help[i], stdout);
  82.         return; }
  83.  
  84.     i = 1;
  85.     while(i < argc) {    /* Stuff all arguments */
  86.         stuff_string(argv[i]);
  87.         if(++i < argc)
  88.             stuff_string(" "); }
  89. }
  90.  
  91. /*
  92.  * Stuff a string into the keyboard buffer
  93.  */
  94. stuff_string(ptr)
  95.     char *ptr;
  96. {
  97.     int i, j;
  98.     char c, prefix;
  99.  
  100.     while(c = *ptr++) {
  101.         if(isalpha(c))                    /* Normal "ALPHA" character */
  102.             prefix = alpha_prefix[(c & 0x1F) - 1];
  103.         else if(c == '^') {
  104.             if(isalpha(c = *ptr++))        /* ALPHA control code */
  105.                 prefix = alpha_prefix[(c &= 0x1F) - 1];
  106.             else switch(c) {
  107.                 default:
  108.                     for(i=0; i < sizeof(misc_key); ++i)
  109.                         if(c == misc_key[i]) {
  110.                             stuff_key(misc_code[i]);
  111.                             goto done; }
  112.                     clear_buffer();
  113.                     abort("Unknown ^!\n");
  114.                 case '.' :                /* Normal function key */
  115.                     prefix = 0x3B;
  116.                     goto dofunc;
  117.                 case ',' :                /* Shift function key */
  118.                     prefix = 0x54;
  119.                     goto dofunc;
  120.                 case ':' :                /* CTRL function key */
  121.                     prefix = 0x5E;
  122.                     goto dofunc;
  123.                 case ';' :                /* ALT function key */
  124.                     prefix = 0x68;
  125.                 dofunc:
  126.                     if(isdigit(c = *ptr++)) {
  127.                         prefix += (c == '0') ? 9 : (c - '1');
  128.                         c = 0;
  129.                         break; }
  130.                     clear_buffer();
  131.                     abort("Fkey must be 0-9\n");
  132.                 case '?' :                /* Clear buffer */
  133.                     clear_buffer();
  134.                     continue;
  135.                 case '*' :                /* ALT-ALPHA character */
  136.                     prefix = alpha_prefix[(*ptr++ & 0x1F) - 1];
  137.                     c = 0; } }
  138.         else {
  139.             for(i=0; j = ascii_prefix[i]; ++i)
  140.                 if((j & 255) == c) {
  141.                     stuff_key(j);
  142.                     goto done; }
  143.             clear_buffer();
  144.             abort("Unknown character\n"); }
  145.         stuff_key((prefix << 8) | c);
  146.     done: }
  147. }
  148.  
  149. /*
  150.  * Stuff a single keystroke into the keyboard buffer
  151.  */
  152. stuff_key(key)
  153.     unsigned key;
  154. {
  155.     unsigned head;
  156.  
  157.     disable();
  158.     pokew(BIOS_SEG, head = peekw(BIOS_SEG, BUFFER_HEAD), key);
  159.  
  160.     if((head += 2) >= peekw(BIOS_SEG, BUFFER_END))
  161.         head = peekw(BIOS_SEG, BUFFER_START);
  162.  
  163.     if(head == peekw(BIOS_SEG, BUFFER_TAIL)) {
  164.         clear_buffer();
  165.         abort("Key buffer FULL!\n"); }
  166.  
  167.     if(head != peekw(BIOS_SEG, BUFFER_TAIL))
  168.     pokew(BIOS_SEG, BUFFER_HEAD, head);
  169.     enable();
  170. }
  171.  
  172. /*
  173.  * Clear the keyboard buffer
  174.  */
  175. clear_buffer()
  176. {
  177.     disable();
  178.     pokew(BIOS_SEG, BUFFER_HEAD, peekw(BIOS_SEG, BUFFER_TAIL));
  179.     enable();
  180. }
  181.